import 'dart:convert';
import 'package:cookie_jar/cookie_jar.dart';
import 'package:dio/dio.dart';
import 'package:dio_cookie_manager/dio_cookie_manager.dart';
import 'package:flustars/flustars.dart';
import 'package:flutter_jdshop/net/result_code.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'global_config.dart';
import 'http_mode.dart';

class DioManager {
  static DioManager? _instance;
  Dio? _dio;

  static DioManager? getInstance() {
    _instance ??= DioManager();
    return _instance;
  }

  DioManager() {
    _dio = Dio();
    _dio!.options.headers = {
      'Accept': 'application/json,*/*',
      'Content-Type': 'application/json',
      //'token':''
    };
    _dio!.options.baseUrl = GlobalConfig.baseUrl;
    _dio!.options.connectTimeout = GlobalConfig.connectTimeout;
    _dio!.options.sendTimeout = GlobalConfig.sendTimeout;
    _dio!.options.receiveTimeout = GlobalConfig.receiveTimeout;
    _dio!.options.contentType = Headers.formUrlEncodedContentType;
    _dio!.options.responseType = ResponseType.json;

    _dio!.interceptors.add(LogInterceptor(responseBody: GlobalConfig.isDebug));
    _dio!.interceptors.add(CookieManager(CookieJar()));
  }

  ///get请求  查询
  get(String url, Map<String, dynamic> params, Function successCallBack, Function errorCallBack) async {
    _requestHttp(url, params, successCallBack, errorCallBack, HttpMode.get);
  }

  ///post请求 提交
  post(String url, Map<String, dynamic> params, Function successCallBack, Function errorCallBack) async {
    _requestHttp(url, params, successCallBack, errorCallBack, HttpMode.post);
  }

  ///put请求 修改
  put(String url, Map<String, dynamic> params, Function successCallBack, Function errorCallBack) async {
    _requestHttp(url, params, successCallBack, errorCallBack, HttpMode.put);
  }

  ///delete请求 删除
  delete(String url, Map<String, dynamic> params, Function successCallBack, Function errorCallBack) async {
    _requestHttp(url, params, successCallBack, errorCallBack, HttpMode.delete);
  }

  _requestHttp(
      String url, Map<String, dynamic>? params, Function successCallBack, Function errorCallBack, httpMode) async {
    late Response response;
    try {
      switch (httpMode) {
        case HttpMode.get:
          if (params!.isNotEmpty) {
            response = await _dio!.get(url, queryParameters: params);
          } else {
            response = await _dio!.get(url);
          }
          break;
        case HttpMode.post:
          if (params!.isNotEmpty) {
            response = await _dio!.post(url, data: params);
          } else {
            response = await _dio!.post(url);
          }
          break;
        case HttpMode.put:
          if (params!.isNotEmpty) {
            response = await _dio!.put(url, data: params);
          } else {
            response = await _dio!.put(url);
          }
          break;
        case HttpMode.delete:
          if (params!.isNotEmpty) {
            response = await _dio!.delete(url, queryParameters: params);
          } else {
            response = await _dio!.delete(url);
          }
          break;
        default:
          break;
      }
    } on DioError catch (error) {
      ///请求错误处理
      Response errorResponse;
      if (error.response != null) {
        errorResponse = error.response!;
      } else {
        errorResponse = Response(
            requestOptions: RequestOptions(
                connectTimeout: GlobalConfig.connectTimeout,
                sendTimeout: GlobalConfig.sendTimeout,
                receiveTimeout: GlobalConfig.receiveTimeout,
                path: url));

        switch (error.type) {
          case DioErrorType.connectTimeout:
            errorResponse.statusCode = ResultCode.connectTimeout;
            break;
          case DioErrorType.sendTimeout:
            errorResponse.statusCode = ResultCode.sendTimeout;
            break;
          case DioErrorType.receiveTimeout:
            errorResponse.statusCode = ResultCode.receiveTimeout;
            break;
          case DioErrorType.response:
            errorResponse.statusCode = ResultCode.response;
            break;
          case DioErrorType.cancel:
            errorResponse.statusCode = ResultCode.cancel;
            break;
          default:
            errorResponse.statusCode = ResultCode.error;
            break;
        }
      }
    }
    if (GlobalConfig.isDebug) {
      LogUtil.e('请求url: ' + url);
      LogUtil.e('请求头: ' + _dio!.options.headers.toString());
      if (params!.isEmpty) {
        LogUtil.e('请求参数: ' + params.toString());
      }
      if (response != null) {
        LogUtil.e('返回参数: ' + response.toString());
      }
    }
    String dataStr = json.encode(response.data);
    Map<String, dynamic> dataMap = json.decode(dataStr);
    if (dataMap['result'] != null) {
      successCallBack(dataMap);
    } else {
      Fluttertoast.showToast(msg: "返回数据错误,请稍后再试～～～", toastLength: Toast.LENGTH_SHORT);
    }
    // if (dataMap['errorCode'] == 0 || dataMap['error_code'] == 0) {
    //   successCallBack(dataMap);
    // } else {
    //   Fluttertoast.showToast(msg: dataMap['errorMsg'], toastLength: Toast.LENGTH_SHORT);
    //   _error(errorCallBack, '错误码：' + dataMap['errorCode'].toString() + ',' + response.data.toString());
    // }

    return response.data;
  }

  _error(Function errorCallBack, String error) {
    errorCallBack(error);
  }

  void cancelRequest(CancelToken cancelToken) {
    cancelToken.cancel();
  }
}
